/************************************************************************
**
**  Copyright (C) 2012 John Schember <john@nachtimwald.com>
**  Copyright (C) 2012 Dave Heiland
**
**  This file is part of Sigil.
**
**  Sigil is free software: you can redistribute it and/or modify
**  it under the terms of the GNU General Public License as published by
**  the Free Software Foundation, either version 3 of the License, or
**  (at your option) any later version.
**
**  Sigil is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**  GNU General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with Sigil.  If not, see <http://www.gnu.org/licenses/>.
**
*************************************************************************/


#include <QtCore/QFile>
#include <QtCore/QHashIterator>
#include <QtGui/QFont>
#include <QtGui/QMessageBox>

#include "BookManipulation/Book.h"
#include "BookManipulation/BookReports.h"
#include "Misc/CSSInfo.h"
#include "ResourceObjects/HTMLResource.h"
#include "ResourceObjects/CSSResource.h"
#include "Misc/SettingsStore.h"

QList<BookReports::StyleData *> BookReports::GetHTMLClassUsage(QList<Resource *>html_resources, QList<Resource *>css_resources, QSharedPointer< Book > book)
{
    QList<BookReports::StyleData *> html_classes_usage;

    // Save each CSS file's text so we don't have to reload it when checking each HTML file
    QList<Resource *> css_named_resources;
    QHash<QString, QString> css_text;
    foreach (Resource *resource, css_resources) {
        QString css_filename = "../" + resource->GetRelativePathToOEBPS();
        if (!css_text.contains(css_filename)) {
            CSSResource *css_resource = dynamic_cast<CSSResource *>( resource );
            css_text[css_filename] = css_resource->GetText();
        }
    }

    // Check each file for classes to look for in inline and linked stylesheets
    foreach (Resource *html_resource, html_resources) {
        QString html_filename = html_resource->Filename();

        // Get the unique list of classes in this file
        QStringList classes_in_file = book->GetClassesInHTMLFile(html_filename);    
        classes_in_file.removeDuplicates();

        // Get the linked stylesheets for this file
        HTMLResource *html_type_resource = dynamic_cast<HTMLResource *>( html_resource );
        QStringList linked_stylesheets = book->GetStylesheetsInHTMLFile(html_type_resource);

        // Look at each class from the HTML file
        foreach (QString class_name, classes_in_file) {
            QString found_location;
            QString selector_text;
            QString element_part = class_name.split(".").at(0);
            QString class_part = class_name.split(".").at(1);

            // Save the details for found or not found classes
            BookReports::StyleData *class_usage = new BookReports::StyleData();

            class_usage->html_filename = html_resource->Filename();
            class_usage->html_element_name = element_part;
            class_usage->html_class_name = class_part;

            // Look in each stylesheet
            foreach (QString css_filename, linked_stylesheets) {
                if (css_text.contains(css_filename)) {
                    CSSInfo css_info(css_text[css_filename], true);
                    CSSInfo::CSSSelector* selector = css_info.getCSSSelectorForElementClass( element_part, class_part); 

                    // If class matched a selector in a linked stylesheet, we're done
                    if (selector && (selector->classNames.count() > 0)) {
                        class_usage->css_filename = css_filename;
                        class_usage->css_selector_text = selector->groupText;
                        class_usage->css_selector_position = selector->position;
                        class_usage->css_selector_line = selector->line;
                        break;
                    }
                }
            }

            html_classes_usage.append(class_usage);
        }
    }

    return html_classes_usage;
}

QList<BookReports::StyleData *> BookReports::GetCSSSelectorUsage(QList<Resource *>css_resources, QList<BookReports::StyleData *> html_classes_usage)
{
    QList<BookReports::StyleData *> css_selectors_usage;

    // Now check the CSS files to see if their classes appear in an HTML file
    foreach (Resource *resource, css_resources) {
        CSSResource *css_resource = dynamic_cast<CSSResource *>( resource );
        QString text = css_resource->GetText();
        CSSInfo css_info(text, true);
        QList<CSSInfo::CSSSelector*> selectors = css_info.getClassSelectors();

        foreach (CSSInfo::CSSSelector *selector, selectors) {
            QString css_filename = "../" + resource->GetRelativePathToOEBPS();

            // Save the details for found or not found classes
            BookReports::StyleData *selector_usage = new BookReports::StyleData();

            selector_usage->css_filename = css_filename;
            selector_usage->css_selector_text = selector->groupText;
            selector_usage->css_selector_position = selector->position;
            selector_usage->css_selector_line = selector->line;

            foreach (BookReports::StyleData *html_class, html_classes_usage) {
                if (css_filename == html_class->css_filename && selector->position == html_class->css_selector_position) {
                    selector_usage->html_filename = html_class->html_filename;
                    break;
                }
            }

            css_selectors_usage.append(selector_usage);
        }
    }

    return css_selectors_usage;
}
